added some development tools
[windows-sources.git] / developer / Samples / NET Standard / ParallelExtensionsExtras_Standard / CoordinationDataStructures / ObservableConcurrentDictionary.cs
blob916a3b2299cfc63111a86a2db2ade168523d86ef
1 //--------------------------------------------------------------------------
2 //
3 // Copyright (c) Microsoft Corporation. All rights reserved.
4 //
5 // File: ObservableConcurrentDictionary.cs
6 //
7 //--------------------------------------------------------------------------
9 using System.Collections.Generic;
10 using System.Collections.Specialized;
11 using System.ComponentModel;
12 using System.Threading;
13 using System.Diagnostics;
15 namespace System.Collections.Concurrent
17 /// <summary>
18 /// Provides a thread-safe dictionary for use with data binding.
19 /// </summary>
20 /// <typeparam name="TKey">Specifies the type of the keys in this collection.</typeparam>
21 /// <typeparam name="TValue">Specifies the type of the values in this collection.</typeparam>
22 [DebuggerDisplay("Count={Count}")]
23 public class ObservableConcurrentDictionary<TKey, TValue> :
24 ICollection<KeyValuePair<TKey, TValue>>, IDictionary<TKey, TValue>,
25 INotifyCollectionChanged, INotifyPropertyChanged
27 private readonly SynchronizationContext _context;
28 private readonly ConcurrentDictionary<TKey, TValue> _dictionary;
30 /// <summary>
31 /// Initializes an instance of the ObservableConcurrentDictionary class.
32 /// </summary>
33 public ObservableConcurrentDictionary()
35 _context = AsyncOperationManager.SynchronizationContext;
36 _dictionary = new ConcurrentDictionary<TKey, TValue>();
39 /// <summary>Event raised when the collection changes.</summary>
40 public event NotifyCollectionChangedEventHandler CollectionChanged;
41 /// <summary>Event raised when a property on the collection changes.</summary>
42 public event PropertyChangedEventHandler PropertyChanged;
44 /// <summary>
45 /// Notifies observers of CollectionChanged or PropertyChanged of an update to the dictionary.
46 /// </summary>
47 private void NotifyObserversOfChange()
49 var collectionHandler = CollectionChanged;
50 var propertyHandler = PropertyChanged;
51 if (collectionHandler != null || propertyHandler != null)
53 _context.Post(s =>
55 if (collectionHandler != null)
57 collectionHandler(this, new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset));
59 if (propertyHandler != null)
61 propertyHandler(this, new PropertyChangedEventArgs("Count"));
62 propertyHandler(this, new PropertyChangedEventArgs("Keys"));
63 propertyHandler(this, new PropertyChangedEventArgs("Values"));
65 }, null);
69 /// <summary>Attempts to add an item to the dictionary, notifying observers of any changes.</summary>
70 /// <param name="item">The item to be added.</param>
71 /// <returns>Whether the add was successful.</returns>
72 private bool TryAddWithNotification(KeyValuePair<TKey, TValue> item)
74 return TryAddWithNotification(item.Key, item.Value);
77 /// <summary>Attempts to add an item to the dictionary, notifying observers of any changes.</summary>
78 /// <param name="key">The key of the item to be added.</param>
79 /// <param name="value">The value of the item to be added.</param>
80 /// <returns>Whether the add was successful.</returns>
81 private bool TryAddWithNotification(TKey key, TValue value)
83 bool result = _dictionary.TryAdd(key, value);
84 if (result) NotifyObserversOfChange();
85 return result;
88 /// <summary>Attempts to remove an item from the dictionary, notifying observers of any changes.</summary>
89 /// <param name="key">The key of the item to be removed.</param>
90 /// <param name="value">The value of the item removed.</param>
91 /// <returns>Whether the removal was successful.</returns>
92 private bool TryRemoveWithNotification(TKey key, out TValue value)
94 bool result = _dictionary.TryRemove(key, out value);
95 if (result) NotifyObserversOfChange();
96 return result;
99 /// <summary>Attempts to add or update an item in the dictionary, notifying observers of any changes.</summary>
100 /// <param name="key">The key of the item to be updated.</param>
101 /// <param name="value">The new value to set for the item.</param>
102 /// <returns>Whether the update was successful.</returns>
103 private void UpdateWithNotification(TKey key, TValue value)
105 _dictionary[key] = value;
106 NotifyObserversOfChange();
109 #region ICollection<KeyValuePair<TKey,TValue>> Members
110 void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
112 TryAddWithNotification(item);
115 void ICollection<KeyValuePair<TKey, TValue>>.Clear()
117 ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Clear();
118 NotifyObserversOfChange();
121 bool ICollection<KeyValuePair<TKey, TValue>>.Contains(KeyValuePair<TKey, TValue> item)
123 return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Contains(item);
126 void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
128 ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).CopyTo(array, arrayIndex);
131 int ICollection<KeyValuePair<TKey, TValue>>.Count
133 get { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).Count; }
136 bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly
138 get { return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).IsReadOnly; }
141 bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item)
143 TValue temp;
144 return TryRemoveWithNotification(item.Key, out temp);
146 #endregion
148 #region IEnumerable<KeyValuePair<TKey,TValue>> Members
149 IEnumerator<KeyValuePair<TKey, TValue>> IEnumerable<KeyValuePair<TKey, TValue>>.GetEnumerator()
151 return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator();
154 IEnumerator IEnumerable.GetEnumerator()
156 return ((ICollection<KeyValuePair<TKey, TValue>>)_dictionary).GetEnumerator();
158 #endregion
160 #region IDictionary<TKey,TValue> Members
161 public void Add(TKey key, TValue value)
163 TryAddWithNotification(key, value);
166 public bool ContainsKey(TKey key)
168 return _dictionary.ContainsKey(key);
171 public ICollection<TKey> Keys
173 get { return _dictionary.Keys; }
176 public bool Remove(TKey key)
178 TValue temp;
179 return TryRemoveWithNotification(key, out temp);
182 public bool TryGetValue(TKey key, out TValue value)
184 return _dictionary.TryGetValue(key, out value);
187 public ICollection<TValue> Values
189 get { return _dictionary.Values; }
192 public TValue this[TKey key]
194 get { return _dictionary[key]; }
195 set { UpdateWithNotification(key, value); }
197 #endregion